﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ObservableExtensions.cs" company="JDML Consulting Ltd.">
//   Copyright 2011 Photon Project - http://photon.codeplex.com
// </copyright>
// <summary>
//   Defines the ObservableExtensions type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Photon
{
    using System;
    
    public static class ObservableExtensions
    {
        public static IEventBinder<IObservable<T>, Action<T>> DefaultEventBinder<T>(this IObservable<T> observable)
        {
            return ObservableBinder<T>.Instance;
        }

        public static IEventBinder<IObservable<T>, Action<T>> GetDefaultEventBinder<T>()
        {
            return ObservableBinder<T>.Instance;
        }

        #region Nested type: ObservableBinder

        private class ObservableBinder<T> : IEventBinder<IObservable<T>, Action<T>>
        {
            public static readonly ObservableBinder<T> Instance = new ObservableBinder<T>();

            #region IEventBinder<IObservable<T>,Action<T>> Members

            public string EventName
            {
                get { return "Subscribe"; }
            }

            public Type PublisherType
            {
                get { return typeof(IObservable<T>); }
            }

            public Type EventType
            {
                get { return typeof(Action<T>); }
            }

            object IEventBinder.Add(object publisher, Delegate handler)
            {
                return Add((IObservable<T>)publisher, (Action<T>)handler);
            }

            void IEventBinder.Remove(object publisher, object subscriptionToken, Delegate handler)
            {
                Remove((IObservable<T>)publisher, subscriptionToken, (Action<T>)handler);
            }

            public object Add(IObservable<T> publisher, Action<T> handler)
            {
                return Guard.ArgumentNull("publisher", publisher)
                    .Subscribe(handler);
            }

            public void Remove(IObservable<T> publisher, object subscriptionToken, Action<T> handler)
            {
                Guard.ArgumentNullOrWrongType<IDisposable>("subscriptionToken", subscriptionToken)
                    .Dispose();
            }

            #endregion
        }

        #endregion
    }
}